/**
 * 
 */
package org.xelnaga.defiler.web.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.WebUtils;
import org.xelnaga.defiler.domain.AddressModel;
import org.xelnaga.defiler.domain.ContentletModel;
import org.xelnaga.defiler.domain.OrderItemModel;
import org.xelnaga.defiler.security.SpringSecurityContext;
import org.xelnaga.defiler.service.AddressService;
import org.xelnaga.defiler.service.ContentletService;
import org.xelnaga.defiler.service.OrderService;

/**
 * @author qijb
 *
 */
@Controller
@RequestMapping("/auction/")
public class OrderProcessController {
	public static final String ORDER_IN_SESSION = "ORDER_IN_SESSION";
	@Autowired
	private ContentletService contentletService;
	@Autowired
	private OrderService orderService;
	@Autowired
	private AddressService addressService;
	@Autowired
	private CartCookieGenerator cartCookieGenerator;
	/**
	 * 
	 */
	public OrderProcessController() {
		// TODO Auto-generated constructor stub
	}

	@RequestMapping(value = "addToCart")
	public String addToCart(@ModelAttribute OrderItemForm orderItemForm, HttpServletRequest request, HttpServletResponse response) {
		OrderForm order = getOrder(request);
		if(null != orderItemForm && null != orderItemForm.getOrderItem()) {
			Long contentletInode = orderItemForm.getOrderItem().getContentletInode();
			Integer quantity = orderItemForm.getOrderItem().getQuantity();
			ContentletModel contentlet = contentletService.getByPrimaryKey(contentletInode);
			OrderItemModel item = new OrderItemModel(contentlet);
			item.setQuantity(quantity);
			orderItemForm.setOrderItem(item);
			order.addOrderItem(item);
			cartCookieGenerator.addCookie(response, getCookieValue(order));
		}
		return "page/auction/cart";
	}
	
	@RequestMapping(value = "myCart")
	public String myCart(HttpServletRequest request) {
		getOrder(request);
		return "page/auction/cart";
	}
	
	@RequestMapping(value = "dropGoods")
	public String dropGoods(HttpServletRequest request) {
		String id = request.getParameter("id");
		if(StringUtils.isNotBlank(id) && StringUtils.isNumeric(id)) {
			OrderForm order = getOrder(request);
			order.deleteCartItems(Long.valueOf(id));
		}
		return "redirect:/auction/myCart";
	}
	
	@RequestMapping(value = "updateQuantity")
	public String updateQuantity(HttpServletRequest request) {
		OrderForm order = getOrder(request);
		@SuppressWarnings("unchecked")
		Enumeration<String> names = request.getParameterNames();
		while(names.hasMoreElements()) {
			String name = names.nextElement();
			if(StringUtils.startsWith(name, "goods_number[")) {
				String inode = StringUtils.substringBetween(name, "[", "]");
				if(StringUtils.isNotBlank(inode) && StringUtils.isNumeric(inode)) {
					String q = request.getParameter(name);
					order.updateCartQuantity(Long.valueOf(inode), Integer.valueOf(q));
				}
			}
		}
		return "redirect:/auction/myCart";
	}
	private String getCookieValue(OrderForm order) {
		Collection<OrderItemModel> list = order.getOrderItemList();
		StringBuffer sb = new StringBuffer();
		if(null != list) {
			for(OrderItemModel item : list) {
				sb.append(item.getContentletInode()).append("_")
				  .append(item.getQuantity())
				  .append(",");
			}
		}
		return sb.toString();
	}

	private OrderForm getOrder(HttpServletRequest request) {
		OrderForm order = (OrderForm)request.getSession().getAttribute(ORDER_IN_SESSION);
		if(null == order) {//Not found in session.
			order = new OrderForm();
			order.getOrder().setShipping(13);
			Cookie cookie = WebUtils.getCookie(request, cartCookieGenerator.getCookieName());
			if (cookie != null) {//Found items in cookie.
				String value = cookie.getValue();
				if(!StringUtils.isBlank(value)) {
					String[] values = value.split(",");
					for(String s : values) {//id_quantity
						String[] ids = s.split("_");
						if(ids.length == 2) {//Only parse two item one is id, the other is quanity
							ContentletModel contentlet = contentletService.getByPrimaryKey(Long.valueOf(ids[0]));
							if(null != contentlet) {
								OrderItemModel item = new OrderItemModel(contentlet);
								item.setQuantity(Integer.valueOf(ids[1]));
								order.addOrderItem(item);
							}
						}
					}
				}
			}
			request.getSession().setAttribute(ORDER_IN_SESSION, order);
		} else {
			order.getOrder().setShipping(13);
		}
		return order;
	}

	@RequestMapping(value = "cart/update_cart_quantity")
	@ResponseBody
	public OrderMountMessage updateCartQuantity(HttpServletRequest request) {
		OrderForm order = getOrder(request);
		String t = request.getParameter("t");//inode
		String q = request.getParameter("quantity");
		if(StringUtils.isNotBlank(q) && StringUtils.isNumeric(q)) {
			order.updateCartQuantity(Long.valueOf(t), Integer.valueOf(q));
		}
		OrderMountMessage message = new OrderMountMessage();
		message.setAmount(String.valueOf(order.getOrderTotalPrice()));
		message.setAmountCent(String.valueOf(order.getOrderTotalPrice()));
		message.setObtainPoint(String.valueOf(order.getOrderTotalPrice()));
		return message;
	}
	
	@RequestMapping(value = "cart/delete_cart_items")
	@ResponseBody 
	public String deleteCartItems(@ModelAttribute OrderItemForm orderItemForm, HttpServletRequest request) {
		OrderForm order = getOrder(request);
		String t = request.getParameter("t");//inode
		if(StringUtils.isNotBlank(t) && StringUtils.isNumeric(t)) {
			order.deleteCartItems(Long.valueOf(t));
		}
		return "ok";
	}
	
	@RequestMapping(value = "checkOut")
	public String checkOut(HttpServletRequest request, Model model) {
		String currentUser = (String)WebUtils.getSessionAttribute(request, "userSession");
		if(StringUtils.isBlank(currentUser)) {
			WebUtils.setSessionAttribute(request, "userSession", SpringSecurityContext.getAuthencatedUsername());
		}
		if(StringUtils.isBlank(currentUser) || currentUser.equalsIgnoreCase("anonymousUser")) {
			return "page/auction/checkout-login";
		} else {
			AddressModel address = addressService.getMainByUserName(currentUser);
			if(null == address) {
				address = new AddressModel();
			}
			model.addAttribute("address", address);
			return "page/auction/checkout";
		}
	}
	
	/**
	 * 直接购买，不登录
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "directCheckout")
	public String directCheckout(HttpServletRequest request, Model model) {
		model.addAttribute("address", new AddressModel());
		return "page/auction/checkout";
	}
	
	@RequestMapping(value = "confirm")
	public String confirm(HttpServletRequest request, Model model) {
		String userName = (String)request.getSession().getAttribute("userSession");
		OrderForm orderForm = getOrder(request);
		List<OrderItemModel> items = new ArrayList<OrderItemModel>();
		items.addAll(orderForm.getOrderItemList());
		orderService.createOrder(orderForm.getOrder(), items, userName);
		return "redirect:/auction/done";
	}
	@RequestMapping(value = "done")
	public String checkoutDone(HttpServletRequest request, Model model) {
		OrderForm orderForm = getOrder(request);
		model.addAttribute("order", orderForm.getOrder());
		request.getSession().removeAttribute(ORDER_IN_SESSION);
		return "page/auction/checkout-done";
	}
	@RequestMapping(value = "purchase")
	public String purchase(@ModelAttribute OrderForm orderForm, HttpServletRequest request) {
		OrderForm sessionOrder = getOrder(request);
		orderForm.getOrder().copyTo(sessionOrder.getOrder());
		sessionOrder.getOrder().setShipping(13);
		return "page/auction/confirm";
	}
}
